package cn.xyinping.user.service.impl;

import cn.xyinping.basic.exception.MyException;
import cn.xyinping.basic.util.StrUtils;
import cn.xyinping.user.constant.UserConstant;
import cn.xyinping.user.domain.User;
import cn.xyinping.user.mapper.UserMapper;
import cn.xyinping.user.service.IVerifycodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 用户登陆获取验证码
 * @author 27266
 * @desrciption
 * @date 2021/10/29
 */
@Service
public class VerifycodeServiceImpl implements IVerifycodeService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public void smsCode(Map<String, String> param) {
        String phone = param.get("phone");
        String type = param.get("type");
//        ①手机号不能为空
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(type)) {
            throw new MyException("手机号不能为空");
        }
        String redisKey = null;
        if (type.equals("register")) {  // 用户注册流程
            //  手机号是否存在
            User user = userMapper.findByPhone(phone);
            if (user != null) {
                throw new MyException("手机号已存在");
            }
            redisKey = UserConstant.REGISTER_PREFIX + phone;
            sendCode(redisKey);
        } else if (type.equals("binder")) { // 用户绑定流程
            redisKey = UserConstant.BINDER_PREFIX + phone;
            sendCode(redisKey);
        }
    }
    /**
     * 发送验证码校验
     * @param redisKey
     */
    public void sendCode(String redisKey){
            //   三分钟过期，从redis中取，如果能取到 没有过期
//        key:业务标识加手机号
            Object tmpCode = redisTemplate.opsForValue().get(redisKey);// 如果能在redis取到值就说明发送了验证码，没有取到就说明没有发送验证码
            String code = null;
            if(tmpCode!=null){
//            判断当前验证码是否超过一分钟，没有超过一分钟，直接提示：验证码已发送，请勿重复发送。。。
                String time = tmpCode.toString().split(":")[0]; // 获取时间戳
                if(System.currentTimeMillis()- Long.valueOf(time)<=60000){ // value:"时间戳+code(验证码+id)"  3470975307+":"+code
                    throw new MyException("验证码已发送，请勿重复发送。。。");
                }else {
                    // 超过一分钟，就在发送一次之前的验证码
                    code = tmpCode.toString().split(":")[1]; // 获取验证码
                }
            } else {
                code = StrUtils.getComplexRandomString(4); // 如果取不到随机生成四位数
            }
            // 往redis中存值  1. key:业务标识加电话（因为前台可能在支付宝等功能也要用到电话号所以要加业务标识）
            //               2. value: 时间戳+验证码  时间戳发送后在一分钟内倒计时
            //               3. 3L: 验证码在三分钟之类有效
            //               4. TimeUnit.MINUTES  表示是分钟
            //  因为redis有过期功能，所以可以设定时间短信验证好久过期
            redisTemplate.opsForValue().set(redisKey, System.currentTimeMillis()+":"+code, 3L, TimeUnit.MINUTES);
            // SendMsg.sendSMS(phone, "验证码:"+code+",请三分中内使用");
            System.out.println(code);
    }
}
